package model

import (
	"fmt"
	"log"
	"sync"

	_ "github.com/jinzhu/gorm/dialects/postgres"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

var db *gorm.DB
var once sync.Once

// 配置结构体（推荐使用环境变量）
type DBConfig struct {
	Host     string
	Port     string
	User     string
	Password string
	DBName   string
	SSLMode  string
}

// GetDB 获取数据库实例（安全访问点）
func GetDB() *gorm.DB {
	once.Do(func() {
		cfg := loadDBConfig()
		initDB(cfg)
	})
	return db
}

// 加载数据库配置（支持环境变量）
func loadDBConfig() *DBConfig {
	return &DBConfig{
		Host:     "localhost",
		Port:     "5432",
		User:     "jw238",
		Password: "jw238",
		DBName:   "nocobase",
		SSLMode:  "disable",
	}
}

func initDB(cfg *DBConfig) {
	dsn := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s sslmode=%s",
		cfg.Host, cfg.Port, cfg.User, cfg.DBName, cfg.Password, cfg.SSLMode)

	var err error
	db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
		PrepareStmt: true, // 开启预编译模式
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:  "",   // 表前缀
			NoLowerCase:  true, // 禁止自动转小写
			NameReplacer: nil,  // 禁用默认名称替换器
		},
	})

	if err != nil {
		log.Fatalf("数据库连接失败: %v", err)
	}

	// 配置连接池
	sqlDB, err := db.DB()
	if err != nil {
		log.Fatalf("获取数据库实例失败: %v", err)
	}

	// 建议值（根据实际负载调整）
	sqlDB.SetMaxOpenConns(25)         // 最大连接数
	sqlDB.SetMaxIdleConns(5)          // 空闲连接数
	sqlDB.SetConnMaxLifetime(30 * 60) // 连接最大存活时间(秒)

	// // 自动迁移（根据环境判断）
	// if err := db.AutoMigrate(&Music{}); err != nil {
	// 	log.Printf("自动迁移警告: %v", err)
	// }
}

// func InitDB() {
// 	// PSQL
// 	db, err := gorm.Open("postgres", "host=localhost port=5432 user=jw238 dbname=postgres password=jw238 sslmode=disable")
// 	if err != nil {
// 		log.Fatalf("failed to connect to database: %v", err)
// 	}
// 	DB = db
// 	DB.AutoMigrate(&Music{})
// }

// func InitDB() {
// 	// SQLITE
// 	dbPath := "project.db"

// 	var err error
// 	DB, err = gorm.Open("sqlite3", dbPath)
// 	if err != nil {
// 		log.Fatalf("failed to connect to database: %v", err)
// 	}
// 	log.Printf("connected to database: %s", dbPath)
// 	// 自动迁移表结构
// 	// DB.AutoMigrate(&User{})
// 	DB.AutoMigrate(&Music{})
// }

func CloseDB() {
	sqlDB, err := db.DB()
	if err != nil {
		log.Fatalf("获取数据库实例失败: %v", err)
	}
	sqlDB.Close()
}
